/***********************************************************************
 * Module:  DeleteCommand.java
 * Author:  Nikola
 * Purpose: Defines the Class DeleteCommand
 ***********************************************************************/

package genedit.controller;

import genedit.model.graph.ConnectionPoint;
import genedit.model.graph.GraphElement;
import genedit.model.graph.Link;
import genedit.utility.PainterMap;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;

/**
 * Komanda za brisanje selektovanih elemenata.
 * 
 * @author Nikola
 * @version 1.3 19/12/13
 */
public class DeleteCommand extends Command {
	private Set<GraphElement> deletedElements;


	public DeleteCommand(boolean isUndoable) {
		super(isUndoable);
	}

	public void execute() {
		Iterator<GraphElement> iterator = getIteratorDeletedElements();
		while (iterator.hasNext()) {
			GraphElement current = iterator.next();

			// Ukidanje konekcionih tacaka elemenata radi uklanjanja kasnije
			for (ConnectionPoint cp : current.getConnectionPoints()) {
				Iterator<Link> linkIt = cp.getIteratorStarting();

				while (linkIt.hasNext()) {
					linkIt.next().getStart().setActive(false);
				}

				linkIt = cp.getIteratorEnding();

				while (linkIt.hasNext()) {
					linkIt.next().getEnd().setActive(false);
				}
			}
		}
		// Uklanjanje veza
		for (GraphElement element : getDocument().getModel().getElements()) {
			if (element instanceof Link) {
				Link link = (Link) element;
				if (link.getStart() == null || link.getStart().isActive() == false
						|| (link.getEnd() != null && link.getEnd().isActive() == false)) {
					addDeletedElements(element);
				}
			}
		}

		iterator = getIteratorDeletedElements();

		while (iterator.hasNext()) {
			GraphElement current = iterator.next();

			getDocument().getModel().removeElements(current);
			getDocument().getModel().removeSelectedElements(current);
		}
	}

	public void undo() {
		Iterator<GraphElement> iterator = getIteratorDeletedElements();
		while (iterator.hasNext()) {
			GraphElement current = iterator.next();

			
			if (!(current instanceof Link)) {
				Iterator<ConnectionPoint> it = current.getIteratorConnectionPoints();
				while (it.hasNext()) {
					it.next().setActive(true);
				}
			}
			getDocument().getModel().addElements(current);
			// Treba ovde sada da se pozove na onu hashmapu koja povezuje
			// elemente sa painterima.
			getDocument().addElementPainters(PainterMap.getInstance().getPainter(current));
		}
	}

	public Set<GraphElement> getDeletedElements() {
		if (deletedElements == null)
			deletedElements = new java.util.HashSet<GraphElement>();
		return deletedElements;
	}

	public java.util.Iterator<GraphElement> getIteratorDeletedElements() {
		if (deletedElements == null)
			deletedElements = new java.util.HashSet<GraphElement>();
		return deletedElements.iterator();
	}

	public void setDeletedElements(java.util.Collection<GraphElement> newDeletedElements) {
		removeAllDeletedElements();
		for (java.util.Iterator<GraphElement> iter = newDeletedElements.iterator(); iter.hasNext();)
			addDeletedElements((GraphElement) iter.next());
	}

	public void addDeletedElements(GraphElement newElementPainter) {
		if (newElementPainter == null)
			return;
		if (this.deletedElements == null)
			this.deletedElements = new java.util.HashSet<GraphElement>();
		if (!this.deletedElements.contains(newElementPainter))
			this.deletedElements.add(newElementPainter);
	}

	public void removeDeletedElements(GraphElement oldElementPainter) {
		if (oldElementPainter == null)
			return;
		if (this.deletedElements != null)
			if (this.deletedElements.contains(oldElementPainter))
				this.deletedElements.remove(oldElementPainter);
	}

	public void removeAllDeletedElements() {
		if (deletedElements != null)
			deletedElements.clear();
	}

}